﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class FadeInOut : MonoBehaviour
{
    public struct FadeInOutData
    {
        public int frame;
        public string[] targetColors;
        public string[] replaceColors;
        public bool cilpUnMatch;
        public bool enabledTargetRange;
        public float[] targetRanges;
    }
    private FadeInOutData[] commonConfigData ={
        new(){
            frame=0,
            cilpUnMatch=true,
            targetColors =new string[]{"#000000",},
            replaceColors=new string[] {"#000000",},
        },
        new(){
            frame=9,
            cilpUnMatch=true,
            targetColors =new string[]{"#FFFFFF","#BCBCBC"},
            replaceColors=new string[] {"#7F7F7F","#7F7F7F"},
        },
        new(){
            frame=17,
            cilpUnMatch=true,
            targetColors =new string[]{"#FFFFFF","#BCBCBC"},
            replaceColors=new string[] {"#BCBCBC","#BCBCBC"},
        },
        new(){
            frame=25,
            cilpUnMatch=true,
            targetColors =new string[]{"#FFFFFF","#BCBCBC"},
            replaceColors=new string[] {"#FFFFFF","#BCBCBC"},
        },
        new(){
            frame=57,
            cilpUnMatch=false,
            targetColors =new string[]{"#000000"},
            replaceColors=new string[] {"#00000000"},
        },
    };
    private FadeInOutData[] logoConfigData ={
        new(){
            frame=33,
            cilpUnMatch=false,
            targetColors =new string[]{
                "#E8D020","#E05000"
            },
            replaceColors=new string[] {
                "#485800","#A03000"
            },
        },
        new(){
            frame=41,
            cilpUnMatch=false,
            targetColors =new string[]{
                "#E8D020","#E05000"
            },
            replaceColors=new string[] {
                "#888800","#E05000"
            },
        },
    };


    private FadeInOutData[] titleConfigData ={
        new(){
            frame=33,
            cilpUnMatch=false,
            targetColors =new string[]{
                "#E05000","#E8D020","#A03000","#FFFFFF"
            },
            replaceColors=new string[] {
                "#A03000","#485800","#A03000","#9F9F9F"
            },
        },
        new(){
            frame=41,
            cilpUnMatch=false,
            targetColors =new string[]{
                "#E05000","#E8D020","#A03000","#FFFFFF"
            },
            replaceColors=new string[] {
                "#E05000","#888800","#A03000","#DFDFDF"
            },
        },
        new(){
            frame=49,
            cilpUnMatch=false,
            targetColors =new string[]{
                "#E05000","#E8D020","#A03000","#FFFFFF"
            },
            replaceColors=new string[] {
                "#AB3D00","#E8D020","#A03000","#DFDFDF"
            },
        },
    };
    private FadeInOutData[] billAndLanceConfigData ={
        new(){
            frame=33,
            cilpUnMatch=false,
            targetColors =new string[]{
                //兰斯头发颜色
                "#305080","#4090C0","#60D0E0",
                //比尔头发颜色
                "#FFF090","#E8D020",
                //身体颜色
                "#FF7830","#FFC8B8",
                //衣服颜色
                "#7F7F7F","#BCBCBC",
            },
            replaceColors=new string[] {
                //兰斯头发颜色
                "#305080","#305080","#305080",
                //比尔头发颜色
                "#485800","#485800",
                //身体颜色
                "#A03000","#A03000",
                //衣服颜色
                "#7F7F7F","#7F7F7F",

            },
        },
        new(){
            frame=41,
            cilpUnMatch=false,
            targetColors =new string[]{
                //兰斯头发颜色
                "#305080","#4090C0","#60D0E0",
                //比尔头发颜色
                "#FFF090","#E8D020",
                //身体颜色
                "#FF7830","#FFC8B8",
                //衣服颜色
                "#7F7F7F","#BCBCBC",
            },
            replaceColors=new string[] {
                //兰斯头发颜色
                "#305080","#4090C0","#4090C0",
                //比尔头发颜色
                "#868600","#868600",
                //身体颜色
                "#E05000","#E05000",
                //衣服颜色
                "#7F7F7F","#BCBCBC",

            },
        },
        new(){
            frame=49,
            cilpUnMatch=false,
            targetColors =new string[]{
                //兰斯头发颜色
                "#305080","#4090C0","#60D0E0",
                //比尔头发颜色
                "#FFF090","#E8D020",
                //身体颜色
                "#FF7830","#FFC8B8",
                //衣服颜色
                "#7F7F7F","#BCBCBC",
            },
            replaceColors=new string[] {
                //兰斯头发颜色
                "#305080","#4090C0","#60CFE0",
                //比尔头发颜色
                "#E8D020","#E8D020",
                //身体颜色
                "#FF7830","#FF7830",
                //衣服颜色
                "#797979","#BCBCBC",

            },
        },
    };

    private List<FadeInOutData> currentConfigData = null;
    private int lastFadeFrame = -1;

    private Material originalMaterial = null;
    private void Awake()
    {
        Reset();
        if (TryGetComponent(out MaskableGraphic graphic))
        {
            originalMaterial = graphic.material;
        }

        string name = gameObject.name;
        currentConfigData = new List<FadeInOutData>(commonConfigData);
        if ("主题图".Equals(name))
        {
            currentConfigData.AddRange(billAndLanceConfigData);
        }
        else if ("标题".Equals(name))
        {
            currentConfigData.AddRange(titleConfigData);
        }
        else if ("Logo".Equals(name))
        {
            currentConfigData.AddRange(logoConfigData);
        }

        if (currentConfigData != null)
        {
            currentConfigData.Sort((FadeInOutData f1, FadeInOutData f2) =>
            {
                return f2.frame - f1.frame;
            });
            FadeAction(currentConfigData[currentConfigData.Count - 1]);
        }
    }

    public void Reset()
    {
        lastFadeFrame = -1;
    }
    public void UpdateFadeIn(float deltaTime, int framePreSeconds = 60)
    {
        if (currentConfigData != null)
        {
            foreach (FadeInOutData data in currentConfigData)
            {
                float seconds = (float)data.frame / (float)framePreSeconds;
                if (deltaTime >= seconds)
                {
                    if (lastFadeFrame != data.frame)
                    {
                        FadeAction(data);
                        lastFadeFrame = data.frame;
                    }
                    break;
                }
            }
        }
    }

    public void UpdateFadeOut(float deltaTime, int framePreSeconds = 60)
    {
        if (currentConfigData != null)
        {
            int maxFrame = currentConfigData[0].frame;
            for (int i = currentConfigData.Count - 1; i >= 0; i--)
            {
                FadeInOutData data = currentConfigData[i];
                int reverseFrame = maxFrame - data.frame;
                float seconds = (float)reverseFrame / (float)framePreSeconds;
                if (deltaTime >= seconds)
                {
                    if (lastFadeFrame != reverseFrame)
                    {
                        FadeAction(data);
                        lastFadeFrame = reverseFrame;
                    }
                    break;
                }
            }
        }
    }

    private void FadeAction(FadeInOutData data)
    {
        if (originalMaterial != null && TryGetComponent(out MaskableGraphic graphic))
        {
            Material mat = new Material(originalMaterial);
            List<Color> targetColors = new();
            List<Color> replaceColors = new();
            float[] targetRanges = data.targetRanges;
            bool cilpUnMatch = data.cilpUnMatch;
            bool enabledTargetRange = data.enabledTargetRange;
            for (int i = 0; i < data.targetColors.Length; i++)
            {
                targetColors.Add(Utility.ParseHtmlString(data.targetColors[i]));
                replaceColors.Add(Utility.ParseHtmlString(data.replaceColors[i]));
            }
            mat.SetColorArray("TargetColors", targetColors);
            mat.SetColorArray("ReplaceColors", replaceColors);
            mat.SetInt("colorSize", targetColors.Count);
            mat.SetInt("_CilpUnMatch", cilpUnMatch ? 1 : 0);
            mat.SetInt("_EnabledTargetRanges", enabledTargetRange ? 1 : 0);
            if (enabledTargetRange)
            {
                mat.SetFloatArray("TargetRanges", targetRanges);
            }

            mat.SetInt("colorSize", targetColors.Count);
            graphic.material = mat;
        }

    }


    void Update()
    {

    }

    public static Material GetFadeMaterial(FadeInOutData configData){
        string[] targetHTMLColor = configData.targetColors;
        string[] replaceHTMLColor = configData.replaceColors;
        Material mat = new Material(Constant.Materials.FadeIn.Load());
        List<Color> targetColors = new();
        List<Color> replaceColors = new();
        float[] targetRanges = configData.targetRanges;
        bool enabledTargetRange = configData.enabledTargetRange;
        bool cilpUnMatch = configData.cilpUnMatch ;
        for (int i = 0; i < targetHTMLColor.Length; i++)
        {
            targetColors.Add(Utility.ParseHtmlString(targetHTMLColor[i]));
            replaceColors.Add(Utility.ParseHtmlString(replaceHTMLColor[i]));
        }
        mat.SetColorArray("TargetColors", targetColors);
        mat.SetColorArray("ReplaceColors", replaceColors);
        mat.SetInt("colorSize", targetColors.Count);
        mat.SetInt("_CilpUnMatch", cilpUnMatch ? 1 : 0);
        mat.SetInt("_EnabledTargetRanges", enabledTargetRange ? 1 : 0);
        if (enabledTargetRange)
        {
            mat.SetFloatArray("TargetRanges", targetRanges);
        }

        mat.SetInt("colorSize", targetColors.Count);        

        return mat;
    }
}
